home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / yamp16.zip / VDOUB.TEX < prev    next >
Text File  |  1992-06-08  |  9KB  |  225 lines

  1. \chapter{Virtual Vector of Doubles}
  2.  
  3. The virtual matrix class is derived from a class of a
  4. vector of doubles stored in the virtual memory system. The
  5. virtual vector gives the matrix class access to the virtual
  6. memory. Holub\cite{Ho:pr} developed a class of integer
  7. vectors with a set of overloaded operators. He created the
  8. class to ease access to the vmm, and demonstrate several
  9. aspects of using classes. Here, the integer class was
  10. rewritten for doubles, and the operators were stripped in
  11. favor of using them on the matrices.
  12.  
  13. Again, the virtual vector should be considered another
  14. intermediate step in creating the virtual matrix class. It is
  15. not needed in the in-ram version, since matrices are allocated
  16. on the heap. Instead a structure is used to store a vector
  17. allocated by calloc, and the number of references to the
  18. structure. This will be explaned in more detail in the chapter
  19. on the stack.
  20.  
  21. \section{vdoub}
  22. The virtual vector of doubles\index{vdoub } is declared in
  23. the following class statement
  24.  
  25. \begin{verbatim}
  26. class vdoub{
  27.  
  28.   protected:
  29.   
  30.     unsigned signature;// garbage flag;
  31.     hdr *hdr;          // virtual memory handle
  32.     double *cur_ele;   // current element
  33.     long  cur_index;   // current index
  34.     //static int nobj;
  35.  
  36.     friend double val( vdoub &v);
  37.   
  38.   public:
  39.   
  40.     int Garbage( void ){ return  !( signature == SIGNATURE ); }
  41.  
  42.     vdoub ( long array_size );
  43.     vdoub ( void );
  44.     vdoub ( vdoub &src );
  45.     ~vdoub( void );
  46.  
  47.     double v( long index );          // get value
  48.     vdoub& operator[]( long index ); // store value
  49.     double operator = ( double d );
  50.     double operator = ( vdoub &v );
  51. };
  52. \end{verbatim}
  53.  
  54. Note that the access to the vmm is in a protected section
  55. of the definition. The matrix class needs access to some of
  56. these elements. 
  57.  
  58. \subsection{Protected Part of a vdoub}
  59. The signature is a garbage flag. It is set to zero when the
  60. vector is deleted. It also serves as a check for the front of
  61. the class being overwritten by rogue functions. The hdr is
  62. a pointer to a vmm header created by vmalloc. 
  63.  
  64. The cur\_ele is a pointer to the current element being
  65. addressed in the virtual vector. The cur\_index is the index
  66. of the current index in the vector. Note the index is a
  67. long, so index operations must be cast on long integers.  
  68. These two variables help control which buffer is stored in
  69. the vmem of the hdr. The member function val() returns the
  70. current value.
  71.  
  72. The static integer, nobj, counts the number of active
  73. vectors. If it is zero, then the vmm system is initialized
  74. in the constructors. The constructors increment nobj and
  75. the destructors decrement nobj.
  76.  
  77. The in-ram version\index{vdoub!IN-RAM vdoub} also sets up a
  78. virtual vector structure, but its memory is allocated entirely
  79. on the heap. The structure is
  80. \begin{verbatim}
  81. typedef struct vdoub{
  82.     int nrefs;
  83.     double HUGE_POINTER *mm;
  84. } vdoub;
  85. \end{verbatim}
  86. The variable, nrefs, stores the number of references to this
  87. vector. The vector pointer *mm is not freed until nrefs is zero.
  88. Note this is a typedef instead of class, so the in-ram virtual
  89. matrix is not derived from vdoub. Also note that mm is now a
  90. vector of huge double pointers. When using Microsoft C/C++ 7.0,
  91. HUGE\_POINTER is replaced by \_\_huge, and it is replaced by far in
  92. Borland C++. If you port the IN\_RAM version to other compilers,
  93. HUGE\_POINTER\index{vdoub!HUGE\_POINTER} is defined as blank. You
  94. can redefine it if you compiler has problems releasing large
  95. blocks of memory when the pointer type of mm is undeclared.
  96. (This occured in an early release of MSC7.0).
  97.  
  98. \subsection{Public Parts of a vdoub}
  99. The public functions give access to the vmm. The function
  100. Garbage()\index{vdoub!Garbage()} simply checks if the signature is
  101. correct. This indicates that the vdoub is likely intact and
  102. active. 
  103.  
  104. The constructors\index{vdoub!constructors} accept void,
  105. long or vdoub\&  arguments.  The default constructor
  106. accepts a void. It allocates a hdr on the vmm with one
  107. double. The second constructor does the same, but the hdr
  108. contains array\_size elements. The constructor with a vdoub
  109. reference argument copies one vdoub into another. Each
  110. constructor increments nobj, and calls
  111. vopen()\index{vmm!vopen()} if nobj is zero.
  112.  
  113. The destructor\index{vdoub!destructor} frees the header. If
  114. the hdr is freed with error, the system stops. Otherwise,
  115. the signature is set to zero and nobj is decremented. If
  116. nobj is decremented to zero, then vclose()\index{vmm!vclose()}
  117. is called. Note that this does not guarantee that vclose()
  118. will be called when the program leaves the main() function
  119. because some virtual matrices are constructed outside of
  120. the scope of main(). The matrix stack dispatcher is a
  121. pointer to the base of a stack of matrices. It is allocated
  122. outside of the function main() so it will not be destroyed
  123. upon leaving main().  Thus, vclose() must be called before
  124. leaving main(). The next time the destructor is called,
  125. vfree() will return an error so the program will exit
  126. through the last destructor call.
  127.  
  128. The function v()\index{vdoub!v()} gets the value at index.
  129. It calls vread() and returns the value. It also sets
  130. cur\_index to index, and stores the current value in
  131. *cur\_ele. Note that the call to vread() may change the
  132. page the buffer in vmem.
  133.  
  134. The brackets operator\index{vdoub![] operator} provides
  135. the same function as v(), but you can use the vector
  136. notation to do it. However it is basically very different
  137. than accessing an element on the heap, or some offset from
  138. a pointer base. The call to vread() shifts a new page into
  139. RAM if necessary. The normal use of the brackets operator
  140. just accesses RAM. This has side effects in the assignment
  141. operation on virtual vectors.
  142.  
  143. The difference between v() and the brackets operator is
  144. they have different return types. v() returns a double and
  145. vdoub::operator[] returns a reference to another vdoub. To
  146. quote Holub: 
  147. \begin{quote}
  148. The brackets operator is a {\em selector } operator. It
  149. sets things up so that the next operation can access the
  150. array element selected by the previous bracket. If the {\em
  151. next} operation modifies the array element, then that
  152. operation sets the dirty bit.
  153. \end{quote}  
  154.  
  155. \section{Assignment in vdoub} 
  156.  
  157. Assignment\index{vdoub!=} takes two forms for virtual vectors. The problem
  158. is to make the code work for saying \verb+ vect[i] = 5+ or
  159. for saying \verb+ vect1 = vect2+. The first form of
  160. assignment is 
  161. \begin{verbatim}
  162. double vdoub::operator = ( double d )
  163.   {
  164.     if ( Garbage() ) {
  165.       perror("VMS assignment error, source is Garbage(=)");
  166.       exit(1);
  167.     }
  168.     *cur_ele = d;
  169.     vdirty( hdr );
  170.     return d;
  171.   }
  172. \end{verbatim}
  173.  
  174. The functional form of \verb+ vect[i] = 5+ is 
  175. \verb+ (vect.operator[](i)).operator=(5)+. First the
  176. brackets operator is called, which sets the current index
  177. to i.  Since the bracket operator returns a reference to a
  178. vdoub, the vdoub::operator=(5) is called.  The current
  179. element of the returned vdoub is set to 5. Next the buffer
  180. is declared dirty, and the 5 is returned.
  181.  
  182. The other form of assignment copies a double vector to
  183. another. It disposes the left operand hdr if it already
  184. exists, then allocates a new hdr. Then it copies the
  185. contents from v to the new hdr. The code is given by
  186.  
  187. \begin{verbatim}
  188. double vdoub::operator = ( vdoub &v)
  189. // copy vector v to vector t
  190.   {
  191.      if( v.Garbage() ){
  192.        perror("VMS copy error, source is Garbage");
  193.        exit(1);
  194.      }
  195.     if( !Garbage() ) vfree( hdr ); // replace hdr if t is active
  196.  
  197.     double *p;
  198.     long numele = vele( v.hdr );
  199.     signature = SIGNATURE;
  200.     *cur_ele = *v.cur_ele;
  201.     cur_index = v.cur_index;
  202.     
  203.     if ( !(hdr = vmalloc( numele, sizeof( double )))) {
  204.       perror(" VMS copy allocation error");
  205.       exit(1);
  206.     }
  207.     while( --numele >= 0 ) {
  208.       if ( !(p = (double *) vread( v.hdr, numele))){
  209.         perror("VMS copy-access( read ) error");
  210.         exit(1);
  211.       }
  212.       if (!vwrite(hdr, numele,(char *)p)){
  213.         perror("VMS copy-access( write ) error");
  214.         exit(1);
  215.       }
  216.     }
  217.     return *cur_ele;
  218.   }
  219. \end{verbatim}
  220.  
  221. This code fragment really emphasizes how well the vdoub
  222. class insulates the user from the vmm system. You don't
  223. have to remember all of the arguments for vread, vwrite,
  224. and vmalloc. You also have a good deal of error checking
  225. embedded in the assignment operators.